
import Layout from './utils/Layout.js'
import MyTree from './utils/MyTree.js'

// 对比两个对象
class Judge2obj {
    constructor() { }
    // 各种类型对比封装 这个是函数的入口
    constrast2obj(o1, o2) {
        // 元素为字符串
        if (typeof o1 === "string" && typeof o2 === "string") {
            return this.judge2StrOrNum(o1, o2)
        }
        // 元素为数字
        else if (typeof o1 === "number" && typeof o2 === "number") {
            return this.judge2StrOrNum(o1, o2)
        }
        // 元素为布尔值
        else if (typeof o1 === "number" && typeof o2 === "number") {
            return this.judge2StrOrNum(o1, o2)
        }
        // 元素为null
        else if (o1 === null && o2 === null) {
            return true
        }
        // 元素为undefined
        else if (o1 === undefined && o2 === undefined) {
            return true
        }
        // 元素为json对象
        else if (this.judgeIsNotJsonObj(o1) && this.judgeIsNotJsonObj(o2)) {
            if (this.judge2Obj(o1, o2)) {
                return true
            } else {
                return false
            }
        }
        // 元素为数组
        else if (o1 instanceof Array && o2 instanceof Array) {
            if (this.judge2Arr(o1, o2)) {
                return true
            } else {
                return false
            }
        } else {
            return false
        }
    }

    // 判断一个对象是不是json对象
    judgeIsNotJsonObj(_obj) {
        let cla = typeof _obj
        if (_obj !== null && !(_obj instanceof Array) && cla === "object") {
            return true
        }
        return false
    }

    // 判断两个字符串、数字、布尔值、null、undefined
    judge2StrOrNum(son1, son2) {
        return son1 === son2
    }

    // 对比两个数组
    judge2Arr(arr1, arr2) {
        if (arr1.length !== arr2.length) {
            return false
        }
        let count = 0
        for (let i = 0; i < arr1.length; i++) {
            if (this.constrast2obj(arr1[i]), arr2[i]) {
                count++
            }
        }
        if (count === arr1.length) {
            return true
        } else {
            return false
        }
    }

    // 对比两个对象是否全等
    judge2Obj(obj1, obj2) {
        let count1 = 0, count2 = 0
        for (const key2 in obj2) {
            for (const key1 in obj1) {
                if (this.constrast2obj(key1, key2) && this.constrast2obj(obj1[key1], obj2[key2])) {
                    count1++
                }
                count2++
            }
            if (count1 === count2) {
                return true
            }
            return false
        }
    }
}

let spanman = {
    MyTree: MyTree,
    Layout: Layout,

    /**
      * 判断是否被 转码 true=是的 false=不是的
      * @param {判断内容} text 
      * @returns 
      */
    isEncoded(text) {
        var decodedText = decodeURI(text);
        return decodedText !== text;
    },

    /**
     * 用屏幕宽高来大致判断是电脑还是手机 返回值是 pc | phone
     * @returns pc | phone
     */
    pcOrPhone: () => {
        // 获取网页的宽高
        let w = document.documentElement.clientWidth || document.body.clientWidth;
        let h = document.documentElement.clientHeight || document.body.clientHeight;
        // 判断是否是手机
        if (w > h) {
            return 'pc';
        } else {
            return 'phone';
        }
    },

    /**
    * 获取文件名
    * @param {路径} p 
    * @param {是否带上文件扩展名 默认带=true} withExtension
    */
    getFileName(p, withExtension = true) {
        let arr = p.split(/(\\|\/)/g)
        let name = arr[arr.length - 1]
        if (!withExtension) {
            name = name.split(".")[0]
        }
        return name
    },
    /**
     * 获取文件 类型后缀名
     * @param {路径} p 
     */
    getFileTypeName(p) {
        let arr = p.split(/(\\|\/)/g)
        let name = arr[arr.length - 1]
        if (name.indexOf(".") != -1) {
            return name.split(".")[1]
        }
        return ""
    },
    /**
     * 获取文件 所在文件夹名字
     * @param {路径} p 
     * @param {是否全路径 默认是=true 否=false=只有文件紧挨的那一层} isCompletePath
     */
    getFileInDirName(p, isCompletePath = true) {
        let arr = p.split(/(\\|\/)/g)
        arr.pop()
        if (isCompletePath) {
            return arr.join("/")
        }
        return arr[arr.length - 2]
    },


    // 复制到剪切板
    copyToClipboard(text) {
        navigator.clipboard.writeText(text).then(function () {
            console.log('Text copied to clipboard');
        }, function () {
            console.error('Could not copy text to clipboard');
        });
    },

    // 获取星期几 中文 或 英文
    getWeek(time = new Date(), type = "zh_CN") {
        // let week = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"]
        let week = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
        let weekEn = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
        if (type === "zh_CN") {
            return week[time.getDay()]
        } else if (type === "en_US") {
            return weekEn[time.getDay()]
        }
    },
    // 获取cookie
    getCookie(name) {
        let strCookie = document.cookie;
        let arrCookie = strCookie.split("; ");
        for (let i = 0; i < arrCookie.length; i++) {
            let arr = arrCookie[i].split("=");
            if (arr[0] === name) {
                return arr[1];
            }
        }
        return "";
    },
    // 取 a对象 中的一些key放到 b对象 中 默认是素有的key，可设置
    getDataFormObj(obj, keys = Object.keys(obj)) {
        let newObj = {}
        keys.map(key => {
            newObj[key] = obj[key]
        })
        return newObj
    },
    // 深拷贝
    /**
     * 深拷贝 返回深拷贝对象
     * @param {深拷贝对象} _obj 
     * @returns 
     */
    // deepCopy(_obj) {
    //     return JSON.parse(JSON.stringify(_obj))
    // },
    // 判断包装类型的原型
    isType(obj, type) {
        return Object.prototype.toString.call(obj).indexOf(type) !== -1
    },
    /**
     * 深拷贝2.0
     * @param {深拷贝的对象} initalObj 
     */
    deepCopy(initalObj) {
        if (typeof initalObj !== "object") {
            return initalObj
        }
        if (this.isType(initalObj, "String") ||
            this.isType(initalObj, "Number") ||
            this.isType(initalObj, "Boolean")
        ) {
            return initalObj.valueOf()
        }
        if (this.isType(initalObj, "Date")) {
            return new Date(initalObj.valueOf())
        }
        if (this.isType(initalObj, "RegExp")) {
            let pattern = initalObj.valueOf()
            let flags = ""
            flags += pattern.global ? "g" : ""
            flags += pattern.ignoreCase ? "i" : ""
            flags += pattern.multiline ? "m" : ""
            return new RegExp(pattern, flags)
        }
        const obj = Array.isArray(initalObj) ? [] : {}
        for (const key in initalObj) {
            // 对象元素
            if (typeof initalObj[key] === "object") {
                // 递归返回新的对象
                obj[key] = this.deepCopy(initalObj[key])
            }
            // 对于函数用bind拷贝
            else if (typeof initalObj[key] === "function") {
                // 返回新的函数
                obj[key] = initalObj[key].bind(obj)
            }
            // 基本类型直接返回
            else {
                obj[key] = initalObj[key]
            }
        }
        return obj
    },
    /**
     * 方法1 使用 map 数据对象进行深拷贝
     * 解释 typeof xxx 的结果有8种可能 
     * undefined boolean number string symbol function object bigint
     * 这样解释下面的代码即是 除了 object 这种比较特殊的数据类型其他都可直接去赋值进行拷贝
     * 剩下object之后再将其针对 数组=[] 这 对象={} 两种具体情况进行处理即可
     * 在处理对象和数组的时候巧妙使用循环和递归
     * @param {*} params 
     */
    deepCopy3(params) {
        const objectMap = new Map();
        const _deepClone = (value) => {
            const type = typeof value;
            if (type !== 'object' || type === null) {
                return value;
            }
            if (objectMap.has(value)) {
                return objectMap.get(value);
            }
            const result = Array.isArray(value) ? [] : {};
            objectMap.set(value, result);
            for (const key in value) {
                result[key] = _deepClone(value[key])
            }
            return result
        }
        return _deepClone(params)
    },
    /**
     * 删除数组中某项 返回值是被删的对象数组
     * @param {数组} _arr 
     * @param {将被删除的项} _item 
     */
    remove(_arr, _item) {
        if (_arr.length) {
            let index = _arr.indexOf(_item)
            if (index > -1) {
                return _arr.splice(index, 1)
            }
        }
    },
    /**
     * 获取日期时间，若只想传时间戳，第一个参数可给空（"" null undefined）
     * @param {时间格式} _format 默认是 YYYY-MM-DD hh:mm:ss
     * @param {时间戳} _timestamp 若不给则是当前时间
     */
    getDate(_format = "YYYY-MM-DD hh:mm:ss", _timestamp = new Date().getTime()) {
        if (!_format) {
            _format = "YYYY-MM-DD hh:mm:ss"
        }
        let date = new Date(Number(_timestamp))

        let year = date.getFullYear() + ""
        let month = (date.getMonth() + 1).toString().padStart(2, "0")
        let day = date.getDate().toString().padStart(2, "0")

        let hour = date.getHours().toString().padStart(2, "0")
        let minute = date.getMinutes().toString().padStart(2, "0")
        let second = date.getSeconds().toString().padStart(2, "0")

        function rep(_str, _value) {
            if (_format.includes(_str)) {
                _format = _format.replace(_str, _value)
            }
        }

        rep("YYYY", year)
        rep("MM", month)
        rep("DD", day)
        rep("hh", hour)
        rep("mm", minute)
        rep("ss", second)

        return _format
    },
    /**
     * 没有 _key 时数组应为[1,2,3,4]
     * 有 _key 时 其为对象数组，此时用_key做唯一值去重
     * @param {数组} _arr 
     * @param {key} _key 
     */
    unique(_arr, _key) {
        if (!_key) {
            return Array.from(new Set(_arr))
        } else {
            let t = []
            _arr.map(item => {
                if (!t.some(it => it[_key] === item[_key])) {
                    t.push(item)
                }
            })
            return t
        }
    },
    /**
     * 处理excel中的 sheetname 长度
     * @param {sheetname原来的字符} arg 
     * @returns 
     */
    formate_sheet_name(arg) {
        if (!arg) {
            return ""
        }
        let res = ""
        let re = /[\\\/\?\*\[\]]+/g; // 不能输入特殊字符
        if (re.test(arg)) {
            res = arg.replace(re, "")
        } else {
            res = arg.valueOf()
        }
        // 不能超过31个字符
        if (res.length > 31) {
            return res.substring(0, 31)
        } else {
            return res
        }
    },
    judge2Obj(...args) {
        if (args.length !== 2) {
            console.log("入参错误")
            return
        }
        let judge2Obj = new Judge2obj()
        return judge2Obj.constrast2obj(...args)
    },

    // 延时函数 类似 pyhton sleep
    delay(duration = 1000) {
        const start = Date.now();
        while (Date.now() - start < duration) { }
    },
    sleep(t) {
        return this.delay(t)
    },

    // 拷贝内容到剪切板
    copy2ClipBoard(text) {
        var input = document.createElement('input');
        input.value = text;
        input.setAttribute('readonly', '');
        input.style.position = 'absolute';
        input.style.left = '-9999px';
        document.body.appendChild(input);
        input.select();
        document.execCommand('copy');
        document.body.removeChild(input);
    },
    // 获取随机正整数
    getRandom(min = 1, max = 10) {
        return Math.floor(Math.random() * (max + 1 - min) + min)
    },
    // 是否为偶数
    isEven(n) {
        return n % 2 === 0
    },
    // 是否为奇数
    isOdd(n) {
        return n % 2 === 1 || n % 2 === -1
    },


    // ==========================================================
    // ==========================================================
    // ==========================================================
    // ==========================================================


    /**
       * 查询某文件夹下指定文件类型的文件，返回其相关数据同时按照创建时间进行排序
       * @param {文件夹路径} _p 
       * @param {指定文件类型} _file_type_arr 
       * @param {正序 倒叙（默认倒叙=desc=后生成的排在前面）} _sorting 
       * @returns 
       */
    get_target_files() { },
    /**
     * 铺某条路径，若路径不存在则一步步创建
     * @param {路径} p 
     */
    make_path(p) { },
    /**
     * 图片转base64返回字符串，可直接使用在img的stc中
     * @param {图片链接地址} _img_path 
     * @returns 
     */
    img_2_base64(_img_path) { },
    /**
     * 批量 图片 转换 base64 文件
     * @param {文件路径} o_data_path 
     * @param {生成的base64存放地址} target_data_path 
     * @param {需要匹配的文件类型} all_pic_type 
     */
    imgs_2_base64s(o_data_path, target_data_path, all_pic_type = ["jpg", "png"]) { },
    // 找出文件中的所有注释 删除其 存在新的文件
}

if (typeof window !== 'undefined') {
    window.spanman = spanman;
}

export default spanman;